package com.hengpeng.common.scheduling;

import java.util.Date;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.annotation.Autowired;

import com.hengpeng.common.cis.ComponentContextLoader;
import com.hengpeng.common.configuration.CachedSystemConfig;
import com.hengpeng.common.exception.ServiceResult;
import com.hengpeng.common.persist.entity.AbstractEntity.BoolValue;
import com.hengpeng.common.scheduling.entity.SystemJob;
import com.hengpeng.common.scheduling.entity.SystemJob.SystemJobState;

public abstract class AbstractJob implements Command
{
	public static final String SYSTEM_STATUS_KEYS = "SYSTEM_STATUS";// 系统状态系统参数Key值

	public static final String SYSTEM_STATUS_RUNNING = "1";// 系统正常运行

	public static final String SYSTEM_STATUS_STOP = "0";// 系统停止

	public AbstractJob()
	{
		this.jobSerivce = ComponentContextLoader.getBean(SystemJobService.class);
	}

	// 首次启动要检查任务状态
	private static Boolean flag = false;

	public static Log log = LogFactory.getLog(AbstractJob.class);

	@Autowired
	protected SystemJobService jobSerivce;

	private void checkSystemJob()
	{
		if (!flag)
		{
			synchronized (flag)
			{
				if (!flag)
				{
					int num = jobSerivce.resetAllSystemJob();
					log.info("共有[" + num + "]个任务状态被重置");
					flag = true;
				}
			}
		}
	}

	/**
	 * <pre>
	 * 任务调度开始
	 * </pre>
	 */
	public void excute(ScheduleConfig config) throws Exception
	{
		// 初次启动时，把定时作业的状态全部改成 等待运行
		checkSystemJob();
		// 检查系统是否正在正常运行
		String systemStatus = CachedSystemConfig.getInstance()
				.getConfigValue(SYSTEM_STATUS_KEYS, SYSTEM_STATUS_RUNNING);
		if ("0".equalsIgnoreCase(systemStatus))
		{
			return;
		}

		boolean isTimeout = false;

		SystemJob systemJob = jobSerivce.checkJob(this.getClass().getName(), config.getName(), config.getDescript());
		if (systemJob.getCanRun() == BoolValue.NO)
		{
			log.info(systemJob.getTaskName() + "作业的状态为{" + systemJob.getCanRun() + "},不可调度");
			return;
		}
		long timeout = config.getTimeOut();
		if ((systemJob.getRunState() == SystemJobState.RUNING) && (timeout != -1))
		{
			// 如果任务正在运行,且有加入超时处理
			long runtimeNum = new Date().getTime() - systemJob.getLastStartTime().getTime();
			if (runtimeNum > timeout)
			{
				// 工作超时
				isTimeout = true;
			}
		}
		if (systemJob.getRunState() == SystemJobState.WAITING || isTimeout)
		{
			boolean isSuccess = true;
			ServiceResult<SystemJob> result = jobSerivce.execSystemJob(systemJob.getClassName(), timeout);
			if (result.getReturnValue() != null)
			{
				// long start = new Date().getTime();
				try
				{
					exec(isTimeout, config);
				}
				catch (Exception ex)
				{
					log.error("执行定时任务{" + systemJob.getTaskName() + "}出现异常.", ex);
					isSuccess = false;
				}
				// long end = new Date().getTime();
				// log.info(this.taskName + " 完成，耗时:" + (end - start));
				jobSerivce
						.execOverSystemJob(systemJob.getClassName(), isSuccess, result.getReturnValue().getRunCount());
			}
			else
			{
				log.info("任务[" + systemJob.getTaskName() + "]正在运行中...");
			}
		}
		else
		{
			log.info("任务[" + systemJob.getTaskName() + "]上次任务还没有完成,等下次执行");
			return;
		}
	}

	/**
	 * <pre>
	 * 具体业务执行 
	 * </pre>
	 * @param isTimeout 上次任务是否超时
	 */
	public abstract void exec(boolean isTimeout, ScheduleConfig config);
}
